﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using xycn.framework.Common;
using xycn.framework.PluginManagement;
/*-------------------------------------------------------
 * �������using������������,��Ҫ�������⿽�������и�Ŀ¼
 *-------------------------------------------------------*/

namespace xycn.framework
{
    public class Program
    {
        /// <summary>
        /// ���windows�Ĵ�������
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="nCmdShow"></param>
        /// <returns></returns>
        [DllImport("user32.dll", EntryPoint = "ShowWindow", SetLastError = true)]
        static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        
        /// <summary>
        /// �������·��
        /// </summary>
        public static string RuntimeDir = "";

        /// <summary>
        /// ��������
        /// </summary>
        public static string ProcName = "";

        /// <summary>
        /// �Ƿ����״̬
        /// </summary>
        public static bool isDebugMode = false;

        public static void Main(string[] args)
        {
            //�жϵ�ǰ���а汾�Ƿ���debug�汾�������debug����������ʾ����
            if (DebugBuild())
            {
                isDebugMode = true;
            }
            else
            {
                //�����release�棬��������������ж��Ƿ����ش���
                foreach (string arg in args)
                {
                    if (arg == "-d") { isDebugMode = true; break; }
                }
            }

            //��ȡ��ǰ���еĳ�������
            FileVersionInfo fi = Process.GetCurrentProcess().MainModule.FileVersionInfo;
            ProcName = fi.FileName;
            ProcName = Path.GetFileName(ProcName);

            //����·�����ݸ� System.IO.Path.GetDirectoryName(path)�����ִ�г������ڵ�Ŀ¼
            RuntimeDir = MultiOSSupportExtension.GetProgramRuntimeDir();

            //���µ�ǰ������ص������⣬�Ա���ز��ʱ�����ظ�����
            //����ͨ�����䴴������ʱ�����´�������ͬ����ܶ���һ��
            GlobalContext.RefreshCurrentLoadAssembly();

            Console.WriteLine("****************���" + ProcName + "���� * ***************",
                Program.isDebugMode);

            //��ָ��Ŀ¼�������л�������������
            string utilitylib_dir =
                MultiOSSupportExtension.CalculateAbsoluteDir(RuntimeDir, "./utility");
            if (Directory.Exists(utilitylib_dir))
            {
                GlobalContext.LoadDefaultSharedLibs(
                    MultiOSSupportExtension.TranslateDirectory(utilitylib_dir));
            }
            else
            {
                Directory.CreateDirectory(utilitylib_dir);
            }

            //��ָ��Ŀ¼���ؿ�ܽӿڿ�
            string interface_dir =
                MultiOSSupportExtension.CalculateAbsoluteDir(RuntimeDir, "./interfaces");
            if (Directory.Exists(interface_dir))
            {
                GlobalContext.LoadDefaultSharedLibs(
                    MultiOSSupportExtension.TranslateDirectory(interface_dir));
            }
            else
            {
                Directory.CreateDirectory(interface_dir);
            }

            //��ȡ�����ļ����������ü���ز��
            if (FrameworkConfig.LoadConfiguration(ProcName + ".xml") < 0)
            {
                Console.WriteLine(FrameworkConfig.errMsg);
            }

            if (!isDebugMode)
            {
                DateTime dt = DateTime.Now;
                string title = "xycn.framework_" +
                    dt.ToString("ddHHmmssffff");
                Console.Title = title;
                //�ȴ�����������Ч
                Thread.Sleep(500);
                IntPtr intptr = FindWindow("ConsoleWindowClass", title);
                if (intptr != IntPtr.Zero)
                {
                    ShowWindow(intptr, 0);//�����������
                }
            }

            //�������
            try
            {
                CreateHostBuilder2(args).Build().Run();
            }
            catch (Exception ex)
            {
                Console.WriteLine("����������ʧ�ܣ�" + ex.Message);
            }

            Console.WriteLine("��������ѹر�,�����س����˳��ն�...");
            Console.ReadLine();
        }
        
        /// <summary>
        /// ����WebHost
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        static IHostBuilder CreateHostBuilder2(string[] args)
        {
            IHostBuilder host_builder = Host.CreateDefaultBuilder(args);
            System.Action<IWebHostBuilder> configure = Configure;
            host_builder.ConfigureWebHostDefaults(configure);
            return host_builder;
        }
        
        /// <summary>
        /// ����WebHost
        /// </summary>
        /// <param name="web_hostbuilder"></param>
        public static void Configure(IWebHostBuilder web_hostbuilder)
        {
            //��������ķ����ַ
            string urls = "";
            foreach (string url in FrameworkConfig.hostUrls)
            {
                if (FrameworkConfig.certificate == null && 
                    url.ToLower().IndexOf("https://") == 0)
                    continue;

                urls = urls + url + ";";
            }

            //����asp.net core �����������
            web_hostbuilder.UseStartup<Startup>()
                .UseUrls(urls)
                .UseKestrel(options =>
                {
                    if (FrameworkConfig.certificate != null)
                    {
                        //�������֤�������֤��
                        options.ConfigureHttpsDefaults(https_option =>
                        {
                            https_option.ServerCertificate = FrameworkConfig.certificate;
                        });
                    }

                    //web�����Ӧ����󳤶�����
                    if (FrameworkConfig.maxResponseBufferSize == 0)
                        options.Limits.MaxResponseBufferSize = null;
                    else
                        options.Limits.MaxResponseBufferSize = FrameworkConfig.maxResponseBufferSize;

                    //web������������󳤶�����
                    if (FrameworkConfig.maxRequestBodySize == 0)
                        options.Limits.MaxRequestBodySize = null;
                    else
                        options.Limits.MaxRequestBodySize = FrameworkConfig.maxRequestBodySize;
                });
        }

        //�Զ����ɴ��룬ΪѧϰASP.net Core��ܣ��޸�Ϊ����Ĵ������ݣ�������������
        /* public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseKestrel().UseUrls("https://0.0.0.0:3001;http://0.0.0.0:3000");
                    webBuilder.UseStartup<Startup>();
                });*/
        
        /// <summary>
        /// �Ƿ�debug�汾
        /// </summary>
        /// <param name="assembly"></param>
        /// <returns></returns>
        private static bool DebugBuild()
        {
            Assembly assembly = Assembly.GetExecutingAssembly();

            foreach (object attribute in assembly.GetCustomAttributes(false))
            {
                if (attribute is DebuggableAttribute)
                {
                    DebuggableAttribute _attribute = attribute as DebuggableAttribute;

                    return _attribute.IsJITTrackingEnabled;
                }
            }
            return false;
        }



        /// <summary>
        /// ���汾�Ƿ��и��¿��
        /// </summary>
        public static void CheckVersion()
        {

        }
    }
}
